package arithmetic.functionTest.myStream;

import java.util.Comparator;
import java.util.Iterator;
import java.util.Objects;
import java.util.Optional;
import java.util.Spliterator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * 简化版:
 * 无拆箱装箱优化
 */
public abstract class MyReferencePipeline<P_IN, P_OUT> extends MyAbstractPipeline<P_IN, P_OUT>
        implements MyStream<P_OUT> {

    /**
     * 构造器继承上个抽象类
     */
    MyReferencePipeline(Supplier<? extends Iterator<?>> source) {
        super(source);
    }

    MyReferencePipeline(Iterator<?> source) {
        super(source);
    }

    MyReferencePipeline(MyAbstractPipeline<?, P_IN> upstream) {
        super(upstream);
    }


    // map方法
    @Override
    public final <R> MyStream<R> map(Function<? super P_OUT, ? extends R> mapper) {
        Objects.requireNonNull(mapper);
        return new StatelessOp<P_OUT, R>(this) {

            @Override
            MySink<P_OUT> opWrapSink(MySink<P_OUT> sink) {
                return new MySink.ChainedReference<P_OUT, R>((MySink<? super R>) sink) {
                    @Override
                    public void accept(P_OUT u) {
                        downstream.accept(mapper.apply(u));
                    }
                };
            }
        };
    }


   /* @Override
    public final MyStream<P_OUT> sort(Comparator<P_OUT> comparator){
        return null;
    }
*/

    @Override
    public final void foreach(Consumer<P_OUT> action){
        evaluate(MyForEachOps.makeRef(action, false));
    }


   /* @Override
    public final Optional<P_OUT> min(Comparator<P_OUT> comparator){
        return Optional.empty();
    }

    @Override
    public final  Optional<P_OUT> max(Comparator<P_OUT> comparator){
        return Optional.empty();
    }
*/

    /**
     * 初始化头
     * @param <E_IN>
     * @param <E_OUT>
     */
    static class Head<E_IN, E_OUT> extends MyReferencePipeline<E_IN, E_OUT> {
        /**
         *
         */
        Head(Supplier<? extends Iterator<?>> source) {
            super(source);
        }

        @Override
        MySink<E_IN> opWrapSink(MySink<E_IN> sink) {
            throw new UnsupportedOperationException();
        }


        Head(Iterator<?> source) {
            super(source);
        }

       /* *//**
         * 头部循环的优化
         * @param action
         *//*
        public void forEach(Consumer<? super E_OUT> action) {
            iterator().forEachRemaining((Consumer<? super E_IN>) action);
        }*/

    }


    /**
     * 无状态中间操作
     * @param <E_IN>
     * @param <E_OUT>
     */
    abstract static class StatelessOp<E_IN, E_OUT>
            extends MyReferencePipeline<E_IN, E_OUT> {

        StatelessOp(MyAbstractPipeline<?, E_IN> upstream) {
            super(upstream);
        }

        /*@Override
        final boolean opIsStateful() {
            return false;
        }*/
    }

}
